home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 751-760 / 758 / mine / txt / mine.mod < prev   
Text File  |  1995-03-18  |  57KB  |  1,789 lines

  1. (************************************************************************************
  2.  
  3. :Program.       Mine
  4.  
  5. :Contents.      neue Implementation eines alten Computer-Spiels
  6.  
  7. :Remark.        benötigt KICK 2.00^
  8.  
  9.  
  10. :Copyright.     "freely distributable copyrighted software"
  11.  
  12. :Author.        Thomas Ansorge
  13.  
  14. :Address.       Dinkelackerring 55, W-6730 Neustadt, Deutschland, Europa
  15.  
  16.  
  17. :Language.      Modula-2
  18.  
  19. :Translator.    M2Amiga V4.096 (deutsch)
  20.  
  21.  
  22. :Imports.       BeepSupport [Thomas Ansorge]
  23. :Imports.       Images [Thomas Ansorge]
  24. :Imports.       OptReqL [Thomas Ansorge]
  25. :Imports.       OptReqToolsL [Thomas Ansorge]
  26. :Imports.       ReqSupport [Thomas Ansorge]
  27.  
  28. :Support.       reqtools.library (Nico François) falls vorhanden, sonst
  29. :Support.       req.library (Colin Fox, Bruce Dawson) falls vorhanden
  30.  
  31. :Support.       viele Tips von Michi
  32.  
  33. :Support.       Fridtjof half debuggen
  34.  
  35.  
  36. :Version.       1.6 vom 21.09.1992
  37.  
  38. :History.       1.0 vom 08.08.1992: es läuft.
  39.  
  40. :History.       1.1 vom 23.08.1992:
  41. :History.           - mit 0-Automatik
  42. :History.           - ab spielfeldMax >= 8: Anzeige Anzahl Fahnen
  43.  
  44. :History.       1.2 vom 11.09.1992:
  45. :History.           - "Zeiger ist NIL"-Bug unter KICK 39.x.
  46. :History.           - Nil-Chk abgestellt (funktioniert oft, hier?)
  47.  
  48. :History.       1.3 vom 11.09.1992: Sicherheitsabfrage PropInfo beim Slider
  49.  
  50. :History.       1.4 vom 14.09.1992:
  51. :History.           - Gadget-Abfrage sicherer
  52. :History.           - Ruhmeshalle einfach per Mausklick verlaßbar
  53. :History.           - Nil-Chk wieder drin.
  54. :History.           - closeWindow beendet jetzt stets das Spiel, die
  55. :History.             Ruhmeshalle wird per Klick ins Fenster verlassen
  56. :History.           - Anzahl Minen in 2 verschiedenen Farben
  57. :History.           - BANG-Requester raus
  58. :History.           - Abfrage "IF gadgetPtr # NIL" im ersten Fenster bei der Abfrage
  59. :History.             der Gadgets nach "IF gadgetUp IN flags". Ist das der Bug unter
  60. :History.             OS 39.x (beta)?
  61. :History.           - Mausklick beendet Minen-Fenster, falls kein Str-Requester
  62.  
  63. :History.       1.5 vom 17.09.1992:
  64. :History.           - Bug in der Programmierung von GadTools behoben (es war eine
  65. :History.             fehlende PropInfo-Struktur)
  66.  
  67. :History.       1.6 vom 21.09.1992:
  68. :History.           - Abfrage der Msg-Ports jetzt gemäß RKM: Libraries
  69. :History.           - explizite Liste der benötigten Lib.-Mindestversionen
  70. :History.           - RefreshWindow jetzt in jedem Fenster
  71.  
  72. ************************************************************************************)
  73.  
  74.  
  75. (*$ DEFINE Deutsch := TRUE *)
  76.  
  77. MODULE Mine;
  78.  
  79. FROM Arts IMPORT Assert;
  80.  
  81. FROM ASCII IMPORT nul;
  82.  
  83. FROM BeepSupport IMPORT Beep, infoPri, Sound;
  84.  
  85. FROM Conversions IMPORT ValToStr;
  86.  
  87. FROM DiskFontL IMPORT diskfontVersion, OpenDiskFont;
  88.  
  89. FROM DosD IMPORT Date, DatePtr;
  90.  
  91. FROM DosL IMPORT dosVersion, DateStamp;
  92.  
  93. FROM ExecL IMPORT execVersion, GetMsg, ReplyMsg, WaitPort;
  94.  
  95. FROM FileSystem IMPORT Close, File, Lookup, ReadByteBlock, Response, WriteByteBlock;
  96.  
  97. FROM GadToolsD IMPORT buttonIDCMP, buttonKind, GtTags, NewGadget, NewGadgetFlags,
  98.    NewGadgetFlagSet, sliderIDCMP, sliderKind;
  99.  
  100. FROM GadToolsL IMPORT CreateContext, CreateGadgetA, DrawBevelBoxA, FreeGadgets,
  101.    FreeVisualInfo, gadtoolsVersion, GetVisualInfoA, GTBeginRefresh, GTEndRefresh, 
  102.    GTGetIMsg, GTRefreshWindow, GTReplyIMsg;
  103.  
  104. FROM GraphicsD IMPORT FontFlagSet, FontStyleSet, jam2, TextAttr, TextFontPtr;
  105.  
  106. FROM GraphicsL IMPORT graphicsVersion, CloseFont;
  107.  
  108. IMPORT Images;
  109.  
  110. FROM InputEvent IMPORT Qualifiers, QualifierSet;
  111.  
  112. FROM IntuitionD IMPORT GadgetPtr, GaTags, IDCMPFlags, IDCMPFlagSet, Image,
  113.    IntuiMessage, IntuiMessagePtr, IntuiText, Screen, ScreenPtr, WaTags, Window,
  114.    WindowFlags, WindowFlagSet, WindowPtr;
  115.  
  116. FROM IntuitionL IMPORT AddGList, BeginRefresh, CloseWindow, DrawImage, EndRefresh,
  117.    intuitionVersion, LockPubScreen, ModifyIDCMP, OpenWindowTagList, PrintIText, 
  118.    RefreshGadgets, RemoveGList, UnlockPubScreen;
  119.  
  120. FROM OptReqL IMPORT reqBase;
  121.  
  122. FROM OptReqToolsL IMPORT reqtoolsBase;
  123.  
  124. IMPORT R;
  125.  
  126. FROM RandomNumber IMPORT PutSeed, RND;
  127.  
  128. FROM RequesterSupport IMPORT noError, ReqLib, TextRequest, StringRequest;
  129.  
  130. FROM String IMPORT Concat, ConcatChar, Copy, Insert;
  131.  
  132. FROM SYSTEM IMPORT ADDRESS, ADR, ASSEMBLE, CAST, TAG;
  133.  
  134. FROM UtilityD IMPORT tagEnd;
  135.  
  136. (* ------------------------------------------------------------------------------- *)
  137.  
  138. (* die Farbverteilung auf der Standard-Workbench *)
  139.  
  140. CONST grau    = 0;
  141.       schwarz = 1;
  142.       weiss   = 2;
  143.       blau    = 3;
  144.  
  145. CONST mineStr = "Mine";
  146.  
  147. CONST sliderGadID = 1;
  148.       weiterGadID = 2;
  149.       infoGadID   = 3;
  150.       ruhmGadID   = 4;
  151.  
  152. (* TAG-Listen *)
  153.  
  154. CONST maxTags = 9;
  155.  
  156. (* der Font *)
  157.  
  158. CONST fontHoehe = 8;
  159.       fontName  = "topaz.font";
  160.  
  161. (*$ IF Deutsch *)
  162.  
  163. CONST info = "Infos und Hilfe";
  164.  
  165.       kick20 = "Mine benötigt KICK 2.00^!";
  166.  
  167.       openWindowError = "konnte Fenster nicht öffnen!";
  168.  
  169.       ruhmeshalleFensterName = "Mine Ruhmeshalle für n = ";
  170.  
  171.       ruhmeshalleGadgetName = "Ruhmeshalle ansehen";
  172.  
  173.       seitenlaenge = "Seitenlänge:";
  174.  
  175.       stringReqTitle = "Mine: Ihren Namen bitte:";
  176.  
  177.       userPortError = "leider kein IDCMP im Fenster!";
  178.  
  179.       weiter = "weiter";
  180.  
  181.       zeitS = "Zeit: ";
  182.  
  183. (*$ ELSE *)
  184.  
  185. CONST info = "infos and help";
  186.  
  187.       kick20 = "Mine needs KICK 2.00^!";
  188.  
  189.       openWindowError = "could not open window!";
  190.  
  191.       ruhmeshalleFensterName = "Mine Highscores for n = ";
  192.  
  193.       ruhmeshalleGadgetName = "show Highscores";
  194.  
  195.       seitenlaenge = "field size :";
  196.  
  197.       stringReqTitle = "Mine: Please enter your name:";
  198.  
  199.       userPortError = "Could not get IDCMP!";
  200.  
  201.       weiter = "continue";
  202.  
  203.       zeitS = "Time: ";
  204.  
  205. (*$ ENDIF *)
  206.  
  207. (* Das Spielfeld *)
  208.  
  209. CONST boxX         = 24;
  210.       boxY         = 12;
  211.       fahne        = -20; (* wird auf Wert addiert *)
  212.       horoffset    = 1;
  213.       mine         = -1;
  214.       nummer       = -3;
  215.       randBreite   = 2;
  216.  
  217. (* Das quadratische Spielfeld *)
  218.  
  219. TYPE Spielfeld = ARRAY [1..77], [1..77] OF SHORTINT;
  220.  
  221. TYPE Zeit = RECORD
  222.                ticks    : [0..49]; (* 50 Ticks pro Sekunde von Intuition *)
  223.                minuten  : LONGINT;
  224.                sekunden : LONGINT;
  225.                zeitStr  : ARRAY [0..11] OF CHAR;
  226.                hilfeStr : ARRAY [0..2] OF CHAR;
  227.                zeitIText: IntuiText;
  228.             END (* RECORD Zeit *);
  229.  
  230. (* Die Ruhmeshalle *)
  231.  
  232. CONST ruhmeshalleName = "Mine-Highscores_";
  233.  
  234. TYPE StringRuhm = ARRAY [0..26] OF CHAR; (* der komplette String mit allem drin! *)
  235.  
  236.      RuhmeshalleEintrag = RECORD
  237.                              anzM: LONGINT;
  238.                              zeit: RECORD
  239.                                       min,
  240.                                       sec: LONGINT;
  241.                                    END (* RECORD Zeit *);
  242.                              name: StringRuhm;
  243.                           END (* RECORD *);
  244.  
  245.      Ruhmeshalle = ARRAY [1..10] OF RuhmeshalleEintrag;
  246.  
  247. VAR anzFahnen       : LONGINT;
  248.     anzMinen        : LONGINT;
  249.     anzNummer       : LONGINT;
  250.     bombeImage      : Image;
  251.     clickedImage    : Image;
  252.     clickmeImage    : Image;
  253.     code            : CARDINAL;
  254.     contextPtr      : GadgetPtr;
  255.     date            : Date;
  256.     eintrag         : RuhmeshalleEintrag;
  257.     ende            : BOOLEAN;
  258.     err             : BOOLEAN;
  259.     explosionImage  : Image;
  260.     fahneImage      : Image;
  261.     fahneORImage    : Image;
  262.     flags           : IDCMPFlagSet;
  263.     fontAttr        : TextAttr;
  264.     fontPtr         : TextFontPtr;
  265.     gadgetPtr       : GadgetPtr;
  266.     gList           : GadgetPtr;
  267.     i               : INTEGER;
  268.     innerWidth      : LONGINT;
  269.     innerHeight     : LONGINT;
  270.     intuiText       : IntuiText;
  271.     j               : INTEGER;
  272.     mausX, mausY    : INTEGER;
  273.     nachricht       : IntuiMessagePtr;
  274.     newGadget       : NewGadget;
  275.     pos             : LONGINT; (* Platz in der Ruhmeshalle *)
  276.     qualifiers      : QualifierSet;
  277.     reqLib          : ReqLib;
  278.     ruhmeshalle     : Ruhmeshalle;
  279.     ruhmeshalleEintr: RuhmeshalleEintrag;
  280.     screenPtr       : ScreenPtr;
  281.     sliderZahlPos   : INTEGER;
  282.     spielfeld       : Spielfeld;
  283.     spielfeldMax    : LONGINT;
  284.     spielFeldMax    : LONGINT;
  285.     string2         : ARRAY [0..2] OF CHAR;
  286.     string30        : ARRAY [0..30] OF CHAR;
  287.     string80        : ARRAY [0..80] OF CHAR;
  288.     tagList         : ARRAY [1..2 * maxTags] OF LONGINT;
  289.     visualInfo      : ADDRESS;
  290.     windowPtr       : WindowPtr;
  291.     windowPtr2      : WindowPtr;
  292.     zeit            : Zeit;
  293.  
  294. (* ------------------------------------------------------------------------------- *)
  295.  
  296. (* Die Prozeduren etc. sind alphabetisch sortiert, daher sind evt. FORWARDs nötig. *)
  297.  
  298. PROCEDURE Ziffer (ziffer: SHORTINT): CHAR; FORWARD;
  299.  
  300. (* ------------------------------------------------------------------------------- *)
  301.  
  302. PROCEDURE AnzMinen (spielfeldMax: LONGINT): LONGINT;
  303.  
  304.    BEGIN (* Funktion AnzMinen *)
  305.  
  306.    RETURN (spielfeldMax * spielfeldMax) DIV 6;
  307. END AnzMinen (* Funktion *);
  308.  
  309. (* ------------------------------------------------------------------------------- *)
  310.  
  311. PROCEDURE DrawClickedImage (VAR windowPtr: WindowPtr;
  312.                             VAR spielfeld: Spielfeld;
  313.                             spielfeldMax : INTEGER;
  314.                             i, j         : INTEGER;
  315.                             VAR anzNummer: LONGINT);
  316.  
  317.    (* spielfeld [i, j] # mine! *)
  318.  
  319.    (* zeichnet das Clicked-Image, schreibt die Anzahl an Minen hinein, falls 0: *)
  320.    (* ruft rekursiv sich selbst auf, bis keine 0 mehr da                        *)
  321.  
  322.    (* i: Zeile, j: Spalte *)
  323.  
  324.    VAR
  325.       intuiText: IntuiText;
  326.       string2  : ARRAY [0..2] OF CHAR;
  327.  
  328.    (* ---------------------------------------------------------------------------- *)
  329.  
  330.    PROCEDURE Farbe (zeile, spalte, anzMinen, max: INTEGER): SHORTCARD;
  331.  
  332.       (* ------------------------------------------------------------------------- *)
  333.  
  334.       PROCEDURE Nachbarn (zeile, spalte, max: INTEGER): INTEGER;
  335.  
  336.          (* macht Gebrauch davon, daß das Spielfeld quadratisch ist *)
  337.  
  338.          BEGIN (* Funktion Nachbarn *)
  339.  
  340.          IF ((zeile = 1) AND (spalte = 1)) OR ((zeile = max) AND (spalte = max)) OR
  341.             ((zeile = 1) AND (spalte = max)) OR ((zeile = max) AND (spalte = 1)) THEN
  342.             RETURN 3;
  343.  
  344.          ELSE (* IF (zeile = spalte) *)
  345.             IF (zeile = 1) OR (spalte = 1) OR (zeile = max) OR (spalte = max) THEN
  346.                RETURN 5; (* Rand, aber keine Ecke *)
  347.  
  348.             ELSE (* IF (zeile = 1 *)
  349.                RETURN 8; (* mittendrin *)
  350.             END (* IF (zeile = 1 *);
  351.          END (* IF (zeile = spalte *);
  352.       END Nachbarn (* Funktion *);
  353.  
  354.       (* ------------------------------------------------------------------------- *)
  355.  
  356.       BEGIN (* Funktion Farbe *)
  357.  
  358.       IF anzMinen = 0 THEN
  359.          RETURN grau;
  360.       END (* IF anzMinen *);
  361.  
  362.       IF Nachbarn (zeile, spalte, max) > (2 * anzMinen) THEN
  363.          RETURN schwarz;
  364.  
  365.       ELSE (* IF (Nachbarn *)
  366.          RETURN blau;
  367.       END (* IF (Nachbarn *);
  368.    END Farbe (* Funktion *);
  369.  
  370.    (* ---------------------------------------------------------------------------- *)
  371.  
  372.    BEGIN (* Prozedur DrawClickedImage *)
  373.  
  374.    DrawImage (windowPtr^.rPort, ADR (clickedImage),
  375.       2 * randBreite + (j - 1) * clickedImage.width + horoffset * (j - 1),
  376.       randBreite + (i - 1) * clickedImage.height);
  377.  
  378.    intuiText.frontPen := Farbe (i, j, spielfeld [i, j], spielfeldMax);
  379.  
  380.    IF intuiText.frontPen # grau THEN
  381.       WITH intuiText DO
  382.          (* frontPen: s. o. *)
  383.          backPen := grau;
  384.          leftEdge := 8;
  385.          topEdge := 2;
  386.          drawMode := jam2;
  387.          iText := ADR (string2);
  388.          iTextFont := ADR (fontAttr);
  389.          nextText := NIL;
  390.       END (* WITH intuiText *);
  391.  
  392.       string2 [0] := Ziffer (spielfeld [i, j]);
  393.       string2 [1] := nul;
  394.  
  395.       PrintIText (windowPtr^.rPort, ADR (intuiText),
  396.          2 * randBreite + (j - 1) * clickedImage.width + horoffset * (j - 1),
  397.          randBreite + (i - 1) * clickedImage.height);
  398.    END (* IF intuiText.frontPen *);
  399.  
  400.    (* 0 soweit vorhanden abräumen *)
  401.  
  402.    IF spielfeld [i, j] = 0 THEN
  403.       spielfeld [i, j] := nummer;
  404.       INC (anzNummer);
  405.  
  406.       IF i # 1 THEN
  407.          IF j # 1 THEN
  408.             IF spielfeld [i - 1, j - 1] >= 0 THEN
  409.                DrawClickedImage (windowPtr, spielfeld, spielfeldMax, i - 1, j - 1,
  410.                   anzNummer);
  411.             END (* IF spielfeld *);
  412.          END (* IF j *);
  413.  
  414.          IF spielfeld [i - 1, j] >= 0 THEN
  415.             DrawClickedImage (windowPtr, spielfeld, spielfeldMax, i - 1, j,
  416.                anzNummer);
  417.          END (* IF spielfeld *);
  418.  
  419.          IF j # spielfeldMax THEN
  420.             IF spielfeld [i - 1, j + 1] >= 0 THEN
  421.                DrawClickedImage (windowPtr, spielfeld, spielfeldMax, i - 1, j + 1,
  422.                   anzNummer);
  423.             END (* IF spielfeld *);
  424.          END (* IF j *);
  425.       END (* IF i # 1 *);
  426.  
  427.       IF j # 1 THEN
  428.          IF spielfeld [i, j - 1] >= 0 THEN
  429.             DrawClickedImage (windowPtr, spielfeld, spielfeldMax, i, j - 1,
  430.                anzNummer);
  431.          END (* IF spielfeld *);
  432.       END (* IF j *);
  433.  
  434.       IF j # spielfeldMax THEN
  435.          IF spielfeld [i, j + 1] >= 0 THEN
  436.             DrawClickedImage (windowPtr, spielfeld, spielfeldMax, i, j + 1,
  437.                anzNummer);
  438.          END (* IF spielfeld *);
  439.       END (* IF j *);
  440.  
  441.       IF i # spielfeldMax THEN
  442.          IF j # 1 THEN
  443.             IF spielfeld [i + 1, j - 1] >= 0 THEN
  444.                DrawClickedImage (windowPtr, spielfeld, spielfeldMax, i + 1, j - 1,
  445.                   anzNummer);
  446.             END (* IF spielfeld *);
  447.          END (* IF j *);
  448.  
  449.          IF spielfeld [i + 1, j] >= 0 THEN
  450.             DrawClickedImage (windowPtr, spielfeld, spielfeldMax, i + 1, j,
  451.                anzNummer);
  452.          END (* IF spielfeld *);
  453.  
  454.          IF j # spielfeldMax THEN
  455.             IF spielfeld [i + 1, j + 1] >= 0 THEN
  456.                DrawClickedImage (windowPtr, spielfeld, spielfeldMax, i + 1, j + 1,
  457.                   anzNummer);
  458.             END (* IF spielfeld *);
  459.          END (* IF j *);
  460.       END (* IF i # spielfeldMax *);
  461.  
  462.    ELSE (* IF spielfeld [i, j] *)
  463.       (* Das ist NICHT wegoptimierbar!!! Sonst dicker BUG!!! *)
  464.       spielfeld [i, j] := nummer;
  465.       INC (anzNummer);
  466.    END (* IF spielfeld [i, j] *);
  467. END DrawClickedImage (* Prozedur *);
  468.  
  469. (* ------------------------------------------------------------------------------- *)
  470.  
  471. PROCEDURE Eor (z1{R.D0}, z2{R.D1}: LONGINT): LONGINT;
  472.  
  473.    BEGIN (* Funktion Eor *)
  474.  
  475.    ASSEMBLE (
  476.       EOR.L D1, D0
  477.    END);
  478.  
  479.    RETURN z1;
  480. END Eor (* Funktion *);
  481.  
  482. (* ------------------------------------------------------------------------------- *)
  483.  
  484. PROCEDURE FuegeEintragEin (VAR ruhmeshalle: Ruhmeshalle;
  485.                            eintrag        : RuhmeshalleEintrag;
  486.                            pos            : LONGINT);
  487.  
  488.    VAR err  : BOOLEAN;
  489.        i    : [1..10];
  490.        hilfe: ARRAY [0..2] OF CHAR;
  491.        str  : ARRAY [0..SIZE (eintrag.name)] OF CHAR;
  492.  
  493.    (* ---------------------------------------------------------------------------- *)
  494.  
  495.    BEGIN (* Prozedur FuegeEintragEin *)
  496.  
  497.    (* Platz schaffen *)
  498.  
  499.    FOR i := 9 TO pos BY -1 DO
  500.       ruhmeshalle [i + 1].anzM := ruhmeshalle [i].anzM;
  501.       ruhmeshalle [i + 1].zeit.min := ruhmeshalle [i].zeit.min;
  502.       ruhmeshalle [i + 1].zeit.sec := ruhmeshalle [i].zeit.sec;
  503.       Copy (ruhmeshalle [i + 1].name, ruhmeshalle [i].name);
  504.    END (* FOR i *);
  505.  
  506.    (* eintragen *)
  507.  
  508.    ValToStr (eintrag.anzM, FALSE, str, 10, 3, " ", err);
  509.    ConcatChar (str, " ");
  510.    ValToStr (eintrag.zeit.min, FALSE, hilfe, 10, 2, "0", err);
  511.    Concat (str, hilfe);
  512.    ConcatChar (str, ":");
  513.    ValToStr (eintrag.zeit.sec, FALSE, hilfe, 10, 2, "0", err);
  514.    Concat (str, hilfe);
  515.    ConcatChar (str, " ");
  516.    Concat (str, eintrag.name);
  517.  
  518.    WITH ruhmeshalle [pos] DO
  519.       anzM := eintrag.anzM;
  520.       zeit.min := eintrag.zeit.min;
  521.       zeit.sec := eintrag.zeit.sec;
  522.       Copy (name, str);
  523.    END (* WITH *);
  524. END FuegeEintragEin (* Prozedur *);
  525.  
  526. (* ------------------------------------------------------------------------------- *)
  527.  
  528. PROCEDURE Info (windowPtr: WindowPtr);
  529.  
  530.    (* zeigt via Text-Requester Infos und Hilfen zum Spiel an *)
  531.  
  532.    (*$ IF Deutsch *)
  533.  
  534.    CONST quitGad = "Quit";
  535.  
  536.    CONST shareware = (* war mal Shareware, daher der Name *)
  537.       "                          Mine © 1992 by\n" +
  538.       "\n" +
  539.       "     Thomas Ansorge, Dinkelackerring 55, W-6730 Neustadt/Weinstaße,\n" +
  540.       "                        Deutschland, Europa\n" +
  541.       "\n" +
  542.       "\n" +
  543.       "\"Mine\" besteht aus den Dateien Mine.deutsch, Mine.english, Mine.dok,\n" +
  544.       "Mine.doc und Mine-Quelltexte.lha.\n" +
  545.       "\n" +
  546.       "Mine ist \"freely distributable copyrighted software\". Sie dürfen es nur\n" +
  547.       "auf nicht-kommerzieller Basis und nur als Ganzes weiterverbreiten und\n" +
  548.       "benutzen, aber alle anderen Rechte bleiben bei mir.\n" +
  549.       "\n" +
  550.       "Die (insgesamt 73) Dateien Mine-Highscores_?? sind von Mine verwaltete\n" +
  551.       "Highscore-Listen, die zwar zu Mine gehören, aber beim Weiterkopieren\n" +
  552.       "weggelassen werden dürfen. Sie sollten allerdings dabei sein.\n" +
  553.       "\n" +
  554.       "Mit Ausnahme der Highscore-Listen (dort ist es erwünscht) darf Mine nicht\n" +
  555.       "verändert werden.\n" +
  556.       "\n" +
  557.       "Da ich für Mine kein Geld verlange, sehe ich auch nicht ein, weshalb ich\n" +
  558.       "irgendeine Verantwortung für Schäden, die durch Mine direkt oder indirekt\n" +
  559.       "verursacht werden, aufkommen soll. SIE BENUTZEN MINE AUF EIGENE GEFAHR!";
  560.  
  561.    CONST sharewareTitel = "Mine:";
  562.  
  563.    CONST spielregeln =
  564.       "Das Spiel Mine funktioniert nach folgenden Regeln:\n" +
  565.       "\n" +
  566.       "Sie haben ein quadratisches Spielfeld mit n * n Feldern. Zufällig über\n" +
  567.       "diese Felder verteilt liegen INTEGER (n * n / 6) Minen versteckt. Diese\n" +
  568.       "gilt es möglichst schnell zu finden. Dazu können Sie die Felder mit der\n" +
  569.       "linken Maustaste anklicken. Ist auf dem Feld eine Mine, explodiert sie\n" +
  570.       "und das Spiel ist zu Ende. Ist keine Mine auf dem Feld, dann enthüllt es\n" +
  571.       "die Anzahl an Minen, die diesem Feld direkt benachbart sind (waagrecht,\n" +
  572.       "senkrecht und diagonal). Glauben Sie eine Mine lokalisiert zu haben, dann\n" +
  573.       "können Sie das entsprechende Feld mit der rechten Maustaste markieren.\n" +
  574.       "\n" +
  575.       "Das Spiel ist zu Ende, wenn eine Mine explodiert oder wenn alle Felder\n" +
  576.       "mit Minen markiert und alle anderen aufgedeckt sind.\n" +
  577.       "\n" +
  578.       "Am Ende entscheiden die Anzahl an markierten Minen und die benötigte\n" +
  579.       "Zeit, ob Sie in die Ruhmeshalle kommen oder nicht.";
  580.  
  581.    CONST spielregelnGad = "Spielregeln";
  582.  
  583.    CONST spielregelnTitel = "Mine: Die Spielregeln";
  584.  
  585.    (*$ ELSE *)
  586.  
  587.    CONST quitGad = "Quit";
  588.  
  589.    CONST shareware =
  590.       "                          Mine © 1992 by\n" +
  591.       "\n" +
  592.       "     Thomas Ansorge, Dinkelackerring 55, W-6730 Neustadt/Weinstraße,\n" +
  593.       "                          Germany, Europe\n" +
  594.       "\n" +
  595.       "\n" +
  596.       "Mine is freely distributable copyrighted software.  You have permission to\n" +
  597.       "distribute Mine to anyone you want on a non-commercial base and as long as\n" +
  598.       "Mine is complete.  All other rights remain at the author alone.\n" +
  599.       "\n" +
  600.       "You are not allowed to change any part of Mine except for the highscore\n" +
  601.       "lists (where you are supposed to...).\n" +
  602.       "\n" +
  603.       "I do not ask for money if you like Mine and can not be made liable for any\n" +
  604.       "damage Mine does to anyone or anything directly or indirectly.  YOU USE\n" +
  605.       "MINE ON YOUR OWN RISK!";
  606.  
  607.    CONST sharewareTitel = "Mine:";
  608.  
  609.    CONST spielregeln =
  610.       "To play mine, you have to follow these simple rules:\n" +
  611.       "\n" +
  612.       "Your field is a n * n square with INTEGER (n * n / 6) hidden mines and\n" +
  613.       "all you have to do is to mark them with a nice flag so that nobody\n" +
  614.       "stumbles over them. The problem: As I said, they are hidden, so you\n" +
  615.       "don't see them. But there is help available: If you click with your\n" +
  616.       "left mouse button on a field that does not contain a mine, it will tell\n" +
  617.       "you the number of mines hidden in its direct neighbourhood. If you hit\n" +
  618.       "a mine with the left mouse button, the game is over. With your right\n" +
  619.       "mouse button you can mark any field with a flag or collect a flag from\n" +
  620.       "a field. You have as many flags as there are mines.\n" +
  621.       "\n" +
  622.       "The game is over if you hit a mine with your left mouse button or if\n" +
  623.       "there is no field without either a number or a flag in it left. Then\n" +
  624.       "the program has a look at the number of mines you marked with a flag\n" +
  625.       "and the time it took and then perhaps you enter the highscorelist.";
  626.  
  627.    CONST spielregelnGad = "how to play Mine";
  628.  
  629.    CONST spielregelnTitel = "Mine: The rules of the game:";
  630.  
  631.    (*$ ENDIF *)
  632.  
  633.    CONST sharewareGads = spielregelnGad + "|" + quitGad;
  634.  
  635.    VAR flags : IDCMPFlagSet;
  636.        nummer: LONGINT;
  637.  
  638.    (* ---------------------------------------------------------------------------- *)
  639.  
  640.    BEGIN (* Prozedur Info *)
  641.  
  642.    flags := IDCMPFlagSet {};
  643.  
  644.    REPEAT
  645.       nummer := TextRequest (shareware, NIL, sharewareGads, sharewareTitel, reqLib,
  646.          flags, windowPtr);
  647.  
  648.       CASE nummer OF
  649.          |1: nummer := TextRequest (spielregeln, NIL, quitGad, spielregelnTitel,
  650.                 reqLib, flags, windowPtr);
  651.  
  652.          |0: (* QUIT: nichts *);
  653.       END (* CASE nummer *);
  654.    UNTIL nummer = 0;
  655. END Info (* Prozedur *);
  656.  
  657. (* ------------------------------------------------------------------------------- *)
  658.  
  659. PROCEDURE InitImages;
  660.  
  661.    (* initialisiert die Images *)
  662.  
  663.    (* alles ist global *)
  664.  
  665.    BEGIN (* Prozedur InitImages *)
  666.  
  667.    WITH bombeImage DO
  668.       leftEdge :=0;
  669.       topEdge :=0;
  670.       width := boxX;
  671.       height := boxY;
  672.       depth := 2;
  673.       imageData := ADR (Images.BombePlane);
  674.       planePick := 3;
  675.       planeOnOff := 0;
  676.       nextImage := NIL;
  677.    END (* WITH bombeImage *);
  678.  
  679.    WITH clickedImage DO
  680.       leftEdge :=0;
  681.       topEdge :=0;
  682.       width := boxX;
  683.       height := boxY;
  684.       depth := 2;
  685.       imageData := ADR (Images.ClickedPlane);
  686.       planePick := 3;
  687.       planeOnOff := 0;
  688.       nextImage := NIL;
  689.    END (* WITH clickedImage *);
  690.  
  691.    WITH clickmeImage DO
  692.       leftEdge :=0;
  693.       topEdge :=0;
  694.       width := boxX;
  695.       height := boxY;
  696.       depth := 2;
  697.       imageData := ADR (Images.ClickMePlane);
  698.       planePick := 3;
  699.       planeOnOff := 0;
  700.       nextImage := NIL;
  701.    END (* WITH clickmeImage *);
  702.  
  703.    WITH explosionImage DO
  704.       leftEdge :=0;
  705.       topEdge :=0;
  706.       width := boxX;
  707.       height := boxY;
  708.       depth := 2;
  709.       imageData := ADR (Images.ExplosionPlane);
  710.       planePick := 3;
  711.       planeOnOff := 0;
  712.       nextImage := NIL;
  713.    END (* WITH explosionImage *);
  714.  
  715.    WITH fahneImage DO
  716.       leftEdge :=0;
  717.       topEdge := 0;
  718.       width := boxX;
  719.       height := boxY;
  720.       depth := 2;
  721.       imageData := ADR (Images.FahnePlane);
  722.       planePick := 3;
  723.       planeOnOff := 0;
  724.       nextImage := NIL;
  725.    END (* WITH fahneImage *);
  726.  
  727.    WITH fahneORImage DO
  728.       leftEdge :=0;
  729.       topEdge := 0;
  730.       width := 12;
  731.       height := 8;
  732.       depth := 2;
  733.       imageData := ADR (Images.FahneORPlane);
  734.       planePick := 3;
  735.       planeOnOff := 0;
  736.       nextImage := NIL;
  737.    END (* WITH fahneImage *);
  738. END InitImages (* Prozedur *);
  739.  
  740. (* ------------------------------------------------------------------------------- *)
  741.  
  742. PROCEDURE LadeRuhmeshalle (VAR ruhmeshalle: Ruhmeshalle;
  743.                            ruhmeshalleName: ARRAY OF CHAR);
  744.  
  745.    (* lädt bzw initialisiert mit 0 die Variable ruhmeshalle *)
  746.  
  747.    VAR file: File;
  748.        i   : [1..10];
  749.  
  750.    (* ---------------------------------------------------------------------------- *)
  751.  
  752.    BEGIN (* Prozedur LadeRuhmeshalle *)
  753.  
  754.    Lookup (file, ruhmeshalleName, SIZE (ruhmeshalle), FALSE);
  755.  
  756.    IF file.res = done THEN
  757.       ReadByteBlock (file, ruhmeshalle);
  758.       Close (file);
  759.  
  760.    ELSE (* IF file.res *);
  761.       FOR i := 1 TO 10 DO
  762.          WITH ruhmeshalle [i] DO
  763.             anzM := 0;
  764.  
  765.             WITH zeit DO
  766.                min := 99;
  767.                sec := 59;
  768.             END (* WITH zeit *);
  769.  
  770.             name := "";
  771.          END (* WITH ruhmeshalle [i] *);
  772.       END (* FOR i *);
  773.    END (* IF file.res *);
  774. END LadeRuhmeshalle (* Prozedur *);
  775.  
  776. (* ------------------------------------------------------------------------------- *)
  777.  
  778. PROCEDURE MaxAnzahlFelder (screenPtr: ScreenPtr): LONGINT;
  779.  
  780.    (* stellt fest, wie groß das auf dem Screen screenPtr gezeichnete Feld maximal  *)
  781.    (* sein kann, damit das ganze Fenster draufpaßt                                 *)
  782.  
  783.    VAR horiz, vert: LONGINT;
  784.  
  785.    (* ---------------------------------------------------------------------------- *)
  786.  
  787.    BEGIN (* Funktion MaxAnzahlFelder *)
  788.  
  789.    horiz := (screenPtr^.width - 2 * 3 - 2 * 4) DIV (boxX + 1);
  790.    vert := (screenPtr^.height - 3 * randBreite - 8 -
  791.       LONGINT (screenPtr^.font^.ySize + CARDINAL (screenPtr^.wBorTop) + 1)) DIV boxY;
  792.  
  793.    IF horiz <= vert THEN
  794.       RETURN horiz;
  795.  
  796.    ELSE
  797.       RETURN vert;
  798.    END (* IF horiz *);
  799. END MaxAnzahlFelder (* Funktion *);
  800.  
  801. (* ------------------------------------------------------------------------------- *)
  802.  
  803. PROCEDURE Pos (ruhmeshalle: Ruhmeshalle;
  804.                eintrag    : RuhmeshalleEintrag (* ohne name *)
  805.               ): LONGINT;
  806.  
  807.    (* stellt den Platz des neuen eintrags in der Ruhmeshalle fest *)
  808.  
  809.    VAR pos: LONGINT;
  810.  
  811.    (* ---------------------------------------------------------------------------- *)
  812.  
  813.    BEGIN (* Prozedur Pos *)
  814.  
  815.    pos := 1;
  816.  
  817.    WHILE (eintrag.anzM < ruhmeshalle [pos].anzM) AND (pos < 10) DO
  818.       INC (pos);
  819.    END (* WHILE *);
  820.  
  821.    IF (pos = 10) AND (eintrag.anzM < ruhmeshalle [pos].anzM) THEN
  822.       RETURN 11;
  823.    END (* IF (pos *);
  824.  
  825.    IF eintrag.anzM > ruhmeshalle [pos].anzM THEN
  826.       RETURN pos;
  827.    END (* IF eintrag.anzM *);
  828.  
  829.    WHILE (eintrag.zeit.min > ruhmeshalle [pos].zeit.min) AND (pos < 10) AND
  830.       (eintrag.anzM = ruhmeshalle [pos].anzM) DO
  831.       INC (pos);
  832.    END (* WHILE *);
  833.  
  834.    IF (pos = 10) AND (eintrag.zeit.min > ruhmeshalle [pos].zeit.min) THEN
  835.       RETURN 11;
  836.    END (* IF (pos *);
  837.  
  838.    IF eintrag.zeit.min < ruhmeshalle [pos].zeit.min THEN
  839.       RETURN pos;
  840.    END (* IF eintrag.zeit.min *);
  841.  
  842.    WHILE (eintrag.zeit.sec >= ruhmeshalle [pos].zeit.sec) AND (pos < 10) AND
  843.       (eintrag.anzM = ruhmeshalle [pos].anzM) AND
  844.       (eintrag.zeit.min = ruhmeshalle [pos].zeit.min) DO
  845.       INC (pos);
  846.    END (* WHILE *);
  847.  
  848.    IF (pos = 10) AND (eintrag.zeit.sec >= ruhmeshalle [pos].zeit.sec) THEN
  849.       RETURN 11;
  850.    END (* IF (pos *);
  851.  
  852.    RETURN pos;
  853. END Pos (* Funktion *);
  854.  
  855. (* ------------------------------------------------------------------------------- *)
  856.  
  857. PROCEDURE SaveRuhmeshalle (ruhmeshalle    : Ruhmeshalle;
  858.                            ruhmeshalleName: ARRAY OF CHAR);
  859.  
  860.    (* speichert die Ruhmeshalle *)
  861.  
  862.    VAR file: File;
  863.  
  864.    (* ---------------------------------------------------------------------------- *)
  865.  
  866.    BEGIN (* Prozedur SaveRuhmeshalle *)
  867.  
  868.    Lookup (file, ruhmeshalleName, SIZE (ruhmeshalle), TRUE);
  869.  
  870.    WriteByteBlock (file, ruhmeshalle);
  871.  
  872.    Close (file);
  873. END SaveRuhmeshalle (* Prozedur *);
  874.  
  875. (* ------------------------------------------------------------------------------- *)
  876.  
  877. PROCEDURE VerteileMinen (VAR spielfeld: Spielfeld;
  878.                          spielfeldMax : LONGINT;
  879.                          anzMinen     : LONGINT);
  880.  
  881.    (* initialisiert das Spielfeld *)
  882.  
  883.    VAR i, j, k: LONGINT;
  884.  
  885.    (* ---------------------------------------------------------------------------- *)
  886.  
  887.    BEGIN (* Prozedur VerteileMinen *)
  888.  
  889.    (* Feld löschen <=> mit 0 füllen *)
  890.  
  891.    FOR i := 1 TO spielfeldMax DO
  892.       FOR j := 1 TO spielfeldMax DO
  893.          spielfeld [i, j] := 0;
  894.       END (* FOR j *);
  895.    END (* FOR i *);
  896.  
  897.    (* Minen nach Zufallsprinzip verteilen und Felder drumherum aktualisieren *)
  898.  
  899.    k := 0;
  900.  
  901.    REPEAT
  902.       i := RND (spielfeldMax) + 1;
  903.       j := RND (spielfeldMax) + 1;
  904.  
  905.       IF spielfeld [i, j] # mine THEN
  906.          (* eine neue Mine *)
  907.          spielfeld [i, j] := mine;
  908.          INC (k);
  909.  
  910.          IF i # 1 THEN
  911.             IF j # 1 THEN
  912.                IF spielfeld [i - 1, j - 1] # mine THEN
  913.                   INC (spielfeld [i - 1, j - 1]); (* links oben *)
  914.                END;
  915.             END;
  916.  
  917.             IF spielfeld [i - 1, j] # mine THEN
  918.                INC (spielfeld [i - 1, j]); (* oben *)
  919.             END;
  920.  
  921.             IF j # spielfeldMax THEN
  922.                IF spielfeld [i - 1, j + 1] # mine THEN
  923.                   INC (spielfeld [i - 1, j + 1]); (* rechts oben *)
  924.                END;
  925.             END;
  926.          END (* IF i # 1 *);
  927.  
  928.          IF j # 1 THEN
  929.             IF spielfeld [i, j - 1] # mine THEN
  930.                INC (spielfeld [i, j - 1]); (* links *)
  931.             END;
  932.          END;
  933.  
  934.          IF j # spielfeldMax THEN
  935.             IF spielfeld [i, j + 1] # mine THEN
  936.                INC (spielfeld [i, j + 1]); (* rechts *)
  937.             END;
  938.          END;
  939.  
  940.          IF i # spielfeldMax THEN
  941.             IF j # 1 THEN
  942.                IF spielfeld [i + 1, j - 1] # mine THEN
  943.                   INC (spielfeld [i + 1, j - 1]); (* links unten *)
  944.                END;
  945.             END;
  946.  
  947.             IF spielfeld [i + 1, j] # mine THEN
  948.                INC (spielfeld [i + 1, j]); (* unten *)
  949.             END;
  950.  
  951.             IF j # spielfeldMax THEN
  952.                IF spielfeld [i + 1, j + 1] # mine THEN
  953.                   INC (spielfeld [i + 1, j + 1]); (* rechts unten *)
  954.                END;
  955.             END;
  956.          END (* IF i # spielfeldMax *);
  957.       END (* IF spielfeld [i, j] # mine *);
  958.    UNTIL k = anzMinen;
  959. END VerteileMinen (* Prozedur *);
  960.  
  961. (* ------------------------------------------------------------------------------- *)
  962.  
  963. PROCEDURE Ziffer (ziffer: SHORTINT): CHAR;
  964.  
  965.    (* Anzahl der Minen um ein Feld *)
  966.  
  967.    BEGIN (* Funktion Ziffer *)
  968.  
  969.    CASE ziffer OF
  970.       |0: RETURN "0";
  971.       |1: RETURN "1";
  972.       |2: RETURN "2";
  973.       |3: RETURN "3";
  974.       |4: RETURN "4";
  975.       |5: RETURN "5";
  976.       |6: RETURN "6";
  977.       |7: RETURN "7";
  978.       |8: RETURN "8";
  979.    END (* CASE ziffer *);
  980. END Ziffer (* Funktion *);
  981.  
  982. (* ------------------------------------------------------------------------------- *)
  983. (* ------------------------------------------------------------------------------- *)
  984.  
  985. BEGIN (* MODULE Mine *)
  986.  
  987. (* okay, was genau brauchen wir: *)
  988.  
  989. Assert (diskfontVersion  >= 33, ADR ("DiskFont Library Version 33 Minimum!"));
  990. Assert (dosVersion       >= 33, ADR ("Dos Library Version 33 Minimum!"));
  991. Assert (execVersion      >= 33, ADR ("Exec Library Version 33 Minimum!"));
  992. Assert (gadtoolsVersion  >= 36, ADR ("GadTools Library Version 36 Minimum!"));
  993. Assert (graphicsVersion  >= 33, ADR ("Graphics Library Version 33 Minimum!"));
  994. Assert (intuitionVersion >= 36, ADR ("Intuition Library Version 36 Minimum!"));
  995.  
  996. IF reqtoolsBase # NIL THEN
  997.    reqLib := reqtools;
  998.  
  999. ELSE (* IF reqtoolsBase *)
  1000.    IF reqBase # NIL THEN
  1001.       reqLib := req;
  1002.  
  1003.    ELSE (* IF reqBase *)
  1004.       reqLib := system;
  1005.    END (* IF reqBase *);
  1006. END (* IF reqtoolsBase *);
  1007.  
  1008. WITH intuiText DO
  1009.    frontPen := schwarz;
  1010.    backPen := grau;
  1011.    drawMode := jam2;
  1012.    iTextFont := ADR (fontAttr);
  1013.    nextText := NIL;
  1014. END (* WITH intuiText *);
  1015.  
  1016. screenPtr := NIL;
  1017. windowPtr := NIL;
  1018. windowPtr2 := NIL;
  1019. visualInfo := NIL;
  1020.  
  1021. DateStamp (ADR (date));
  1022. PutSeed (Eor (date.days, Eor (date.minute, date.tick)));
  1023.  
  1024. (* mein Font *)
  1025.  
  1026. WITH fontAttr DO
  1027.    name := ADR (fontName);
  1028.    ySize := fontHoehe;
  1029.    style := FontStyleSet {};
  1030.    flags := FontFlagSet {};
  1031. END (* WITH fontAttr *);
  1032.  
  1033. fontPtr := OpenDiskFont (ADR (fontAttr));
  1034.  
  1035. spielfeldMax := 10;
  1036.  
  1037. screenPtr := LockPubScreen (NIL);
  1038.  
  1039. LOOP
  1040.    ende := FALSE;
  1041.    anzNummer := 0;
  1042.  
  1043.    WITH zeit DO
  1044.       ticks := 0;
  1045.       minuten := 0;
  1046.       sekunden := 0;
  1047.  
  1048.       WITH zeitIText DO
  1049.          frontPen := schwarz;
  1050.          backPen := grau;
  1051.          drawMode := jam2;
  1052.          leftEdge := 0;
  1053.          topEdge := -1;
  1054.          iTextFont := ADR (fontAttr);
  1055.          iText := ADR (zeitStr);
  1056.          nextText := NIL;
  1057.       END (* WITH zeitIText *);
  1058.    END (* WITH Zeit *);
  1059.  
  1060.    (* das Anfangs-Fenster *)
  1061.  
  1062.    spielFeldMax := MaxAnzahlFelder (screenPtr);
  1063.  
  1064.    IF spielFeldMax > 77 THEN
  1065.       spielFeldMax := 77;
  1066.    END (* IF spielFeldMax *);
  1067.  
  1068.    innerWidth := 180;
  1069.  
  1070.    windowPtr := OpenWindowTagList (NIL, TAG (tagList,
  1071.                    waInnerHeight, 90,
  1072.                    waInnerWidth , innerWidth,
  1073.                    waLeft       , (LONGINT (screenPtr^.width) - 204) DIV 2,
  1074.                    waTop        , (LONGINT (screenPtr^.height) - 70) DIV 2,
  1075.                    waTitle      , ADR (mineStr),
  1076.                    waFlags      , CAST (LONGINT, WindowFlagSet {windowDrag,
  1077.                                                                 windowClose,
  1078.                                                                 gimmeZeroZero,
  1079.                                                                 reportMouse,
  1080.                                                                 activate,
  1081.                                                                 windowDepth}),
  1082.                    waIDCMP      , CAST (LONGINT, IDCMPFlagSet {closeWindow,
  1083.                                                                refreshWindow} +
  1084.                                                  buttonIDCMP +
  1085.                                                  sliderIDCMP),
  1086.                    waPubScreen  , screenPtr,
  1087.                    tagEnd       , 0));
  1088.  
  1089.    Assert (windowPtr # NIL, ADR (openWindowError));
  1090.    Assert (windowPtr^.userPort # NIL, ADR (userPortError));
  1091.  
  1092.    IF visualInfo = NIL THEN
  1093.       visualInfo := GetVisualInfoA (windowPtr^.wScreen, NIL);
  1094.    END (* IF visualInfo *);
  1095.  
  1096.    gList := NIL;
  1097.  
  1098.    contextPtr := CreateContext (gList); (* bereitet gList für GadTools vor *)
  1099.  
  1100.    (* contextPtr und gList zeigen jetzt auf den selben Speicherbereich *)
  1101.  
  1102.    string80 := "5                ";
  1103.  
  1104.    ValToStr (spielFeldMax, FALSE, string2, 10, 2, "0", err);
  1105.    Concat (string80, string2);
  1106.  
  1107.    IF gList # NIL THEN
  1108.       (* der Slider *)
  1109.  
  1110.       WITH newGadget DO
  1111.          width := 154;
  1112.          height := 12;
  1113.          leftEdge := (innerWidth - width) DIV 2;
  1114.          topEdge := 18;
  1115.          gadgetText := ADR (string80);
  1116.          textAttr := ADR (fontAttr);
  1117.          gadgetID := sliderGadID;
  1118.          flags := NewGadgetFlagSet {placetextBelow};
  1119.          userData := NIL;
  1120.       END (* WITH newGadget *);
  1121.  
  1122.       sliderZahlPos := (innerWidth - 160) DIV 2 + 104;
  1123.  
  1124.       newGadget.visualInfo := visualInfo;
  1125.  
  1126.       gadgetPtr := CreateGadgetA (sliderKind, gList^, newGadget, TAG (tagList,
  1127.                       gtslMin        , 5,
  1128.                       gtslMax        , spielFeldMax,
  1129.                       gtslLevel      , spielfeldMax,
  1130.                       gtslMaxLevelLen, 21,
  1131.                       gaRelVerify    , TRUE,
  1132.                       gaImmediate    , TRUE,
  1133.                       tagEnd         , 0));
  1134.  
  1135.       (* weiter *)
  1136.  
  1137.       WITH newGadget DO
  1138.          width := 80;
  1139.          height := 12;
  1140.          leftEdge := (innerWidth - width) DIV 2;
  1141.          topEdge := 45;
  1142.          gadgetText := ADR (weiter);
  1143.          textAttr := ADR (fontAttr);
  1144.          gadgetID := weiterGadID;
  1145.          flags := NewGadgetFlagSet {placetextIn};
  1146.          userData := NIL;
  1147.       END (* WITH newGadget *);
  1148.  
  1149.       newGadget.visualInfo := visualInfo;
  1150.  
  1151.       gadgetPtr := CreateGadgetA (buttonKind, gadgetPtr^, newGadget, NIL);
  1152.  
  1153.       (* Infos und Hilfe *)
  1154.  
  1155.       WITH newGadget DO
  1156.          width := 128;
  1157.          height := 12;
  1158.          leftEdge := (innerWidth - width) DIV 2;
  1159.          topEdge := 60;
  1160.          gadgetText := ADR (info);
  1161.          textAttr := ADR (fontAttr);
  1162.          gadgetID := infoGadID;
  1163.          flags := NewGadgetFlagSet {placetextIn};
  1164.          userData := NIL;
  1165.       END (* WITH newGadget *);
  1166.  
  1167.       newGadget.visualInfo := visualInfo;
  1168.  
  1169.       gadgetPtr := CreateGadgetA (buttonKind, gadgetPtr^, newGadget, NIL);
  1170.  
  1171.       (* Ruhmeshalle ansehen *)
  1172.  
  1173.       WITH newGadget DO
  1174.          width := 160;
  1175.          height := 12;
  1176.          leftEdge := (innerWidth - width) DIV 2;
  1177.          topEdge := 75;
  1178.          gadgetText := ADR (ruhmeshalleGadgetName);
  1179.          textAttr :=ADR (fontAttr);
  1180.          gadgetID := ruhmGadID;
  1181.          flags := NewGadgetFlagSet {placetextIn};
  1182.          userData := NIL;
  1183.       END (* WITH newGadget *);
  1184.  
  1185.       newGadget.visualInfo := visualInfo;
  1186.  
  1187.       gadgetPtr := CreateGadgetA (buttonKind, gadgetPtr^, newGadget, NIL);
  1188.  
  1189.       i := AddGList (windowPtr, gList, 0, -1, NIL);
  1190.       RefreshGadgets (gList, windowPtr, NIL);
  1191.       GTRefreshWindow (windowPtr, NIL); (* für GadTools *)
  1192.    END (* IF gList *);
  1193.  
  1194.    i := 0;
  1195.  
  1196.    (* "Seitenlänge" über Prop-Gadget schreiben *)
  1197.    intuiText.leftEdge := 17;
  1198.    intuiText.topEdge := 0;
  1199.    intuiText.iText := ADR (string80);
  1200.    string80 := seitenlaenge;
  1201.    PrintIText (windowPtr^.rPort, ADR (intuiText), sliderZahlPos - 104, 7);
  1202.  
  1203.    intuiText.iText := ADR (string2);
  1204.    ValToStr (spielfeldMax, FALSE, string2, 10, 2, " ", err);
  1205.    PrintIText (windowPtr^.rPort, ADR (intuiText), sliderZahlPos, 7);
  1206.  
  1207.    REPEAT
  1208.       nachricht := GTGetIMsg (windowPtr^.userPort);
  1209.  
  1210.       IF nachricht = NIL THEN
  1211.          WaitPort (windowPtr^.userPort);
  1212.          nachricht := GTGetIMsg (windowPtr^.userPort);
  1213.       END (* IF nachricht *);
  1214.  
  1215.       IF nachricht # NIL THEN
  1216.          flags := nachricht^.class;
  1217.          gadgetPtr := nachricht^.iAddress;
  1218.          code := nachricht^.code; (* nur bei GadTools UND GTGetIMsg *)
  1219.          GTReplyIMsg (nachricht);
  1220.  
  1221.          IF closeWindow IN flags THEN
  1222.             EXIT (* LOOP *);
  1223.  
  1224.          ELSIF refreshWindow IN flags THEN
  1225.             GTBeginRefresh (windowPtr);
  1226.             GTEndRefresh (windowPtr, TRUE);
  1227.  
  1228.          ELSIF gadgetUp IN flags THEN
  1229.             IF gadgetPtr # NIL THEN
  1230.                i := gadgetPtr^.gadgetID;
  1231.  
  1232.                IF i = infoGadID THEN
  1233.                   Info (windowPtr);
  1234.                END (* IF i *);
  1235.  
  1236.                IF i = ruhmGadID THEN
  1237.                   ValToStr (spielfeldMax, FALSE, string2, 10, 2, " ", err);
  1238.  
  1239.                   Copy (string30, ruhmeshalleName);
  1240.                   Concat (string30, string2);
  1241.  
  1242.                   LadeRuhmeshalle (ruhmeshalle, string30);
  1243.  
  1244.                   innerWidth := 276;
  1245.                   innerHeight := 124;
  1246.  
  1247.                   Copy (string30, ruhmeshalleFensterName);
  1248.                   Concat (string30, string2);
  1249.  
  1250.                   windowPtr2 := OpenWindowTagList (NIL, TAG (tagList,
  1251.                      waTitle      , ADR (string30),
  1252.                      waInnerWidth , innerWidth,
  1253.                      waInnerHeight, innerHeight,
  1254.                      waLeft       , (screenPtr^.width - innerWidth) DIV 2,
  1255.                      waTop        , (screenPtr^.height - innerHeight) DIV 2,
  1256.                      waFlags      , CAST (LONGINT, WindowFlagSet {windowClose,
  1257.                                                                   activate,
  1258.                                                                   windowDrag,
  1259.                                                                   windowDepth,
  1260.                                                                   gimmeZeroZero}),
  1261.                      waIDCMP      , CAST (LONGINT, IDCMPFlagSet {closeWindow,
  1262.                                                                  refreshWindow,
  1263.                                                                  mouseButtons}),
  1264.                      tagEnd       , 0));
  1265.  
  1266.                   Assert (windowPtr2 # NIL, ADR (openWindowError));
  1267.                   Assert (windowPtr2^.userPort # NIL, ADR (userPortError));
  1268.  
  1269.                   (* windowPtr^ und WindowPtr2^ sind auf dem selben Screen, also *)
  1270.                   (* darf ich auch das selbe visualInfo verwenden *)
  1271.  
  1272.                   DrawBevelBoxA (windowPtr2^.rPort, 20, 7, 234, 108, TAG (tagList,
  1273.                      gtbbRecessed, 0,
  1274.                      gtVisualInfo, visualInfo,
  1275.                      tagEnd      , 0));
  1276.  
  1277.                   WITH intuiText DO
  1278.                      leftEdge := 0;
  1279.                      topEdge := 12;
  1280.                   END (* WITH intuiText *);
  1281.  
  1282.                   FOR j := 1 TO 10 DO
  1283.                      IF ruhmeshalle [j].anzM = AnzMinen (spielfeldMax) THEN
  1284.                         intuiText.frontPen := blau;
  1285.                      END (* IF ruhmeshalle *);
  1286.  
  1287.                      intuiText.iText := ADR (ruhmeshalle [j].name);
  1288.                      PrintIText (windowPtr2^.rPort, ADR (intuiText), 34,
  1289.                         10 * (j - 1));
  1290.  
  1291.                      intuiText.frontPen := schwarz;
  1292.                   END (* FOR j *);
  1293.  
  1294.                   flags := IDCMPFlagSet {};
  1295.  
  1296.                   REPEAT
  1297.                      nachricht := GetMsg (windowPtr2^.userPort);
  1298.  
  1299.                      IF nachricht = NIL THEN
  1300.                         WaitPort (windowPtr2^.userPort);
  1301.                         nachricht := GetMsg (windowPtr2^.userPort);
  1302.                      END (* IF nachricht *);
  1303.  
  1304.                      IF nachricht # NIL THEN
  1305.                         flags := nachricht^.class;
  1306.                         ReplyMsg (nachricht);
  1307.                      END (* IF nachricht *);
  1308.                      
  1309.                      IF refreshWindow IN flags THEN
  1310.                         BeginRefresh (windowPtr2);
  1311.                         EndRefresh (windowPtr2, TRUE);
  1312.                      END (* IF refreshWindow *);
  1313.  
  1314.                      IF closeWindow IN flags THEN
  1315.                         EXIT (* LOOP *);
  1316.                      END (* IF closeWindows *);
  1317.                   UNTIL mouseButtons IN flags;
  1318.  
  1319.                   CloseWindow (windowPtr2);
  1320.                   windowPtr2 := NIL;
  1321.                END (* IF i *);
  1322.             END (* IF gadgetPtr # NIL *);
  1323.  
  1324.          ELSIF gadgetDown IN flags THEN
  1325.             IF gadgetPtr # NIL THEN
  1326.                IF gadgetPtr^.gadgetID = sliderGadID THEN
  1327.                   REPEAT
  1328.                      nachricht := GTGetIMsg (windowPtr^.userPort);
  1329.  
  1330.                      IF nachricht = NIL THEN
  1331.                         WaitPort (windowPtr^.userPort);
  1332.                         nachricht := GTGetIMsg (windowPtr^.userPort);
  1333.                      END (* IF nachricht *);
  1334.  
  1335.                      IF nachricht # NIL THEN
  1336.                         flags := nachricht^.class;
  1337.                         code := nachricht^.code;
  1338.                         GTReplyIMsg (nachricht);
  1339.  
  1340.                         IF (mouseMove IN flags) OR (gadgetUp IN flags) THEN
  1341.                            (* jemand bewegt den Slider *)
  1342.                            spielfeldMax := LONGINT (code);
  1343.  
  1344.                            intuiText.leftEdge := 17;
  1345.                            intuiText.topEdge := 0;
  1346.                            intuiText.iText := ADR (string2);
  1347.  
  1348.                            ValToStr (spielfeldMax, FALSE, string2, 10, 2, " ", err);
  1349.                            PrintIText (windowPtr^.rPort, ADR (intuiText),
  1350.                               sliderZahlPos, 7);
  1351.                         END (* IF mouseMove *);
  1352.                      END (* IF nachricht *);
  1353.                   UNTIL gadgetUp IN flags; (* losgelassen *)
  1354.                END (* IF gadgetPtr^. *);
  1355.             END (* IF gadgetPtr *);
  1356.          END (* IF closeWindow *);
  1357.       END (* IF nachricht *);
  1358.    UNTIL i = weiterGadID;
  1359.  
  1360.    FreeVisualInfo (visualInfo);
  1361.    visualInfo := NIL;
  1362.  
  1363.    i := RemoveGList (windowPtr, gList, 5);
  1364.  
  1365.    FreeGadgets (gList);
  1366.    gList := NIL;
  1367.  
  1368.    CloseWindow (windowPtr);
  1369.    windowPtr := NIL;
  1370.  
  1371.    anzMinen := AnzMinen (spielfeldMax);
  1372.  
  1373.    (* spielfeldMax <= 44 (PAL SuperHires-Interlace mit vollem Overscan) *)
  1374.    (* ==>  anzMinen <= 322 *)
  1375.  
  1376.    (* spielfeldMax <= 77 <==> anzMinen dreistellig *)
  1377.  
  1378.    anzFahnen := 0;
  1379.  
  1380.    (* Das eigentliche Spiel-Fenster *)
  1381.  
  1382.    string2 := "";
  1383.  
  1384.    VerteileMinen (spielfeld, spielfeldMax, anzMinen);
  1385.  
  1386.    innerWidth := LONGINT ((spielfeldMax * boxX) + (4 * randBreite) + spielfeldMax -
  1387.       1);
  1388.    innerHeight := LONGINT ((spielfeldMax * boxY) + (2 * randBreite) - 2 + 10);
  1389.  
  1390.    windowPtr := OpenWindowTagList (NIL, TAG (tagList,
  1391.       waTitle      , ADR (mineStr),
  1392.       waInnerWidth , innerWidth,
  1393.       waInnerHeight, innerHeight,
  1394.       waFlags      , CAST (LONGINT, WindowFlagSet {windowDrag, windowDepth,
  1395.                         windowClose, activate, gimmeZeroZero, rmbTrap}),
  1396.       waIDCMP      , CAST (LONGINT, IDCMPFlagSet {mouseButtons, closeWindow,
  1397.                         refreshWindow, intuiTicks}),
  1398.       waLeft       , (screenPtr^.width - innerWidth) DIV 2,
  1399.       waTop        , (screenPtr^.height - innerHeight) DIV 2,
  1400.       waPubScreen  , screenPtr,
  1401.       tagEnd       , 0));
  1402.  
  1403.    Assert (windowPtr # NIL, ADR (openWindowError));
  1404.    Assert (windowPtr^.userPort # NIL, ADR (userPortError));
  1405.  
  1406.    InitImages ();
  1407.  
  1408.    IF spielfeldMax < 8 THEN
  1409.       zeit.zeitIText.leftEdge := (windowPtr^.gzzWidth - 88) DIV 2;
  1410.  
  1411.    ELSE (* IF spielfeldMax *)
  1412.       zeit.zeitIText.leftEdge := (((windowPtr^.gzzWidth DIV 2) - 88 + randBreite)
  1413.          DIV 2) + randBreite;
  1414.  
  1415.       intuiText.topEdge := -1;
  1416.       (* leftEdge: rechts der Mitte, alles 44 Pixel breit, davon FahneORImage 12 *)
  1417.       intuiText.leftEdge := (windowPtr^.gzzWidth DIV 2) +
  1418.          (((windowPtr^.gzzWidth DIV 2) - 44 - randBreite) DIV 2) + 12;
  1419.       intuiText.iText := ADR (string30);
  1420.    END (* IF spielfeldMax *);
  1421.  
  1422.    (* Felder zeichnen *)
  1423.  
  1424.    FOR i := 1 TO spielfeldMax DO (* Zeilen *)
  1425.       FOR j := 1 TO spielfeldMax DO (* Spalten *)
  1426.          DrawImage (windowPtr^.rPort, ADR (clickmeImage),
  1427.             2 * randBreite + (j - 1) * clickmeImage.width + horoffset * (j - 1),
  1428.             randBreite + (i - 1) * clickmeImage.height);
  1429.       END (* FOR j *);
  1430.    END (* FOR i *);
  1431.  
  1432.    Copy (zeit.zeitStr, zeitS);
  1433.    Concat (zeit.zeitStr, "00:00");
  1434.  
  1435.    PrintIText (windowPtr^.rPort, ADR (zeit.zeitIText), 0,
  1436.       2 * randBreite + spielfeldMax * boxY);
  1437.  
  1438.    IF spielfeldMax >= 8 THEN
  1439.       DrawImage (windowPtr^.rPort, ADR (fahneORImage),
  1440.          ((windowPtr^.gzzWidth DIV 2) + ((windowPtr^.gzzWidth DIV 2) - 44) DIV 2) - 1,
  1441.          2 * randBreite + spielfeldMax * boxY - 1);
  1442.  
  1443.       ValToStr (anzMinen - anzFahnen, FALSE, string30, 10, 3, " ", err);
  1444.       Insert (string30, 0, ":\o");
  1445.       PrintIText (windowPtr^.rPort, ADR (intuiText), 0,
  1446.          2 * randBreite + spielfeldMax * boxY);
  1447.    END (* IF spielfeldMax *);
  1448.  
  1449.    (* Aktion des Spielers abwarten und reagieren *)
  1450.  
  1451.    flags := IDCMPFlagSet {};
  1452.  
  1453.    REPEAT
  1454.       nachricht := GetMsg (windowPtr^.userPort);
  1455.  
  1456.       IF nachricht = NIL THEN
  1457.          WaitPort (windowPtr^.userPort);
  1458.          nachricht := GetMsg (windowPtr^.userPort);
  1459.       END (* IF nachricht *);
  1460.  
  1461.       IF nachricht # NIL THEN
  1462.          flags := nachricht^.class;
  1463.          qualifiers := nachricht^.qualifier;
  1464.  
  1465.          mausX := windowPtr^.gzzMouseX;
  1466.          mausY := windowPtr^.gzzMouseY;
  1467.  
  1468.          ReplyMsg (nachricht);
  1469.  
  1470.          (* so, jetzt geht's ans Auswerten *)
  1471.  
  1472.          IF intuiTicks IN flags THEN
  1473.             IF zeit.ticks < 9 THEN
  1474.                INC (zeit.ticks);
  1475.  
  1476.             ELSE (* IF zeit.ticks = 9 *)
  1477.                zeit.ticks := 0;
  1478.  
  1479.                IF zeit.sekunden < 59 THEN
  1480.                   INC (zeit.sekunden);
  1481.  
  1482.                ELSE (* IF zeit.sekunden *)
  1483.                   zeit.sekunden := 0;
  1484.  
  1485.                   IF zeit.minuten < 99 THEN
  1486.                      INC (zeit.minuten);
  1487.  
  1488.                   ELSE (* IF zeit.minuten *)
  1489.                      ende := TRUE;
  1490.                   END (* IF zeit.minuten *);
  1491.                END (* IF zeit.sekunden *);
  1492.  
  1493.                IF NOT ende THEN
  1494.                   WITH zeit DO
  1495.                      Copy (zeitStr, zeitS);
  1496.  
  1497.                      ValToStr (minuten, FALSE, hilfeStr, 10, 2, "0", err);
  1498.                      Concat (zeitStr, hilfeStr);
  1499.  
  1500.                      ConcatChar (zeitStr, ":");
  1501.  
  1502.                      ValToStr (sekunden, FALSE, hilfeStr, 10, 2, "0", err);
  1503.                      Concat (zeitStr, hilfeStr);
  1504.  
  1505.                      PrintIText (windowPtr^.rPort, ADR (zeitIText), 0,
  1506.                         2 * randBreite + spielfeldMax * boxY);
  1507.                   END (* WITH Zeit *);
  1508.                END (* IF NOT ende *);
  1509.             END (* IF zeit.ticks *);
  1510.          END (* IF intuiTicks *);
  1511.          
  1512.          IF refreshWindow IN flags THEN
  1513.             BeginRefresh (windowPtr);
  1514.             EndRefresh (windowPtr, TRUE);
  1515.          END (* IF refreshWindow *);
  1516.  
  1517.          IF mouseButtons IN flags THEN
  1518.             i := ((mausY - randBreite) DIV boxY) + 1; (* Zeile *)
  1519.             j := ((mausX - 2 * randBreite) DIV (boxX + horoffset)) + 1;
  1520.  
  1521.             IF (i >= 1) AND (i <= spielfeldMax) AND (j >= 1) AND
  1522.                (j <= spielfeldMax) THEN
  1523.                (* das Feld [i, j] angeklickt *)
  1524.                IF rightButton IN qualifiers THEN
  1525.                   IF spielfeld [i, j] >= mine THEN
  1526.                      IF anzFahnen < anzMinen THEN
  1527.                         DrawImage (windowPtr^.rPort, ADR (fahneImage),
  1528.                            2 * randBreite + (j - 1) * fahneImage.width +
  1529.                               horoffset * (j - 1),
  1530.                            randBreite + (i - 1) * fahneImage.height);
  1531.  
  1532.                         spielfeld [i, j] := spielfeld [i, j] + fahne;
  1533.  
  1534.                         INC (anzFahnen);
  1535.                      END (* IF anzFahnen *);
  1536.  
  1537.                   ELSE (* IF spielfeld [i, j] >= mine *)
  1538.                      IF spielfeld [i, j] <= fahne + 8 THEN
  1539.                         DrawImage (windowPtr^.rPort, ADR (clickmeImage),
  1540.                            2 * randBreite + (j - 1) * clickmeImage.width +
  1541.                               horoffset * (j - 1),
  1542.                            randBreite + (i - 1) * clickmeImage.height);
  1543.  
  1544.                         spielfeld [i, j] := spielfeld [i, j] - fahne;
  1545.  
  1546.                         DEC (anzFahnen);
  1547.                      END (* IF spielfeld [i, j] = fahne *);
  1548.                   END (* IF spielfeld [i, j] >= mine *);
  1549.  
  1550.                   IF spielfeldMax >= 8 THEN
  1551.                      ValToStr (anzMinen - anzFahnen, FALSE, string30, 10, 3, " ",
  1552.                         err);
  1553.                      Insert (string30, 0, ":\o");
  1554.                      PrintIText (windowPtr^.rPort, ADR (intuiText), 0,
  1555.                         2 * randBreite + spielfeldMax * boxY);
  1556.                   END (* IF spielfeldMax *);
  1557.  
  1558.                ELSIF leftButton IN qualifiers THEN
  1559.                   IF spielfeld [i, j] >= mine THEN
  1560.                      IF spielfeld [i, j] # mine THEN
  1561.                         ModifyIDCMP (windowPtr, IDCMPFlagSet {});
  1562.  
  1563.                         DrawClickedImage (windowPtr, spielfeld, spielfeldMax, i, j,
  1564.                            anzNummer);
  1565.  
  1566.                         ModifyIDCMP (windowPtr,
  1567.                            IDCMPFlagSet {mouseButtons, closeWindow, refreshWindow,
  1568.                               intuiTicks});
  1569.  
  1570.                      ELSE (* IF # mine *)
  1571.                         DrawImage (windowPtr^.rPort, ADR (explosionImage),
  1572.                            2 * randBreite + (j - 1) * explosionImage.width +
  1573.                            horoffset * (j - 1),
  1574.                            randBreite + (i - 1) * explosionImage.height);
  1575.  
  1576.                         Beep (booob, infoPri);
  1577.  
  1578.                         ende := TRUE;
  1579.                      END (* IF # mine *);
  1580.                   END (*IF >= mine *);
  1581.                END (* IF rightButton *);
  1582.             END (* IF (i >= 1 *);
  1583.          END (* IF mouseButtons *);
  1584.       END (* IF nachricht # NIL *);
  1585.    UNTIL ende OR (closeWindow IN flags) OR
  1586.       ((spielfeldMax * spielfeldMax - anzFahnen - anzNummer) = 0);
  1587.  
  1588.    IF closeWindow IN flags THEN
  1589.       CloseWindow (windowPtr);
  1590.       windowPtr := NIL;
  1591.  
  1592.       EXIT (* LOOP *);
  1593.    END (* IF closeWindow *);
  1594.  
  1595.    ModifyIDCMP (windowPtr, IDCMPFlagSet {}); (* keine Nachrichten mehr! *)
  1596.  
  1597.    (* Anzahl der gefundenen Minen zählen *)
  1598.  
  1599.    anzMinen := 0;
  1600.  
  1601.    FOR i := 1 TO spielfeldMax DO
  1602.       FOR j := 1 TO spielfeldMax DO
  1603.          IF spielfeld [i, j] = fahne + mine THEN
  1604.             INC (anzMinen);
  1605.  
  1606.             (* Bombe zeichnen *)
  1607.  
  1608.             DrawImage (windowPtr^.rPort, ADR (bombeImage),
  1609.                2 * randBreite + (j - 1) * clickedImage.width + horoffset * (j - 1),
  1610.                randBreite + (i - 1) * clickedImage.height);
  1611.          END (* IF spielfeld *);
  1612.       END (* FOR j *);
  1613.    END (* FOR i *);
  1614.  
  1615.    IF ((spielfeldMax * spielfeldMax) - anzNummer - anzMinen) = 0 THEN
  1616.       (* alles abgeräumt! *)
  1617.       Beep (beeeb, infoPri);
  1618.    END (* IF ((spielfeldMax *);
  1619.  
  1620.    ValToStr (spielfeldMax, FALSE, string2, 10, 2, " ", err);
  1621.  
  1622.    Copy (string30, ruhmeshalleName);
  1623.    Concat (string30, string2);
  1624.  
  1625.    LadeRuhmeshalle (ruhmeshalle, string30);
  1626.  
  1627.    eintrag.anzM := anzMinen;
  1628.    eintrag.zeit.min := zeit.minuten;
  1629.    eintrag.zeit.sec := zeit.sekunden;
  1630.  
  1631.    pos := Pos (ruhmeshalle, eintrag);
  1632.  
  1633.    IF (pos <= 10) AND (reqLib # system) THEN (* drin -- String-Requester! *)
  1634.       j := StringRequest (eintrag.name, 17, 16, stringReqTitle, windowPtr,
  1635.               reqLib);
  1636.  
  1637.       IF j = noError THEN
  1638.          FuegeEintragEin (ruhmeshalle, eintrag, pos);
  1639.          SaveRuhmeshalle (ruhmeshalle, string30);
  1640.       END (* IF noError *);
  1641.  
  1642.    ELSE (* IF pos *)
  1643.       (* nicht in der Ruhmeshalle -- auf Mausklick warten *)
  1644.       ModifyIDCMP (windowPtr, IDCMPFlagSet {mouseButtons, closeWindow});
  1645.  
  1646.       REPEAT
  1647.          nachricht := GetMsg (windowPtr^.userPort);
  1648.  
  1649.          IF nachricht = NIL THEN
  1650.             WaitPort (windowPtr^.userPort);
  1651.             nachricht := GetMsg (windowPtr^.userPort);
  1652.          END (* IF nachricht *);
  1653.  
  1654.          flags := nachricht^.class;
  1655.          ReplyMsg (nachricht);
  1656.  
  1657.          IF closeWindow IN flags THEN
  1658.             EXIT (* LOOP *);
  1659.          END (* IF closeWindow *);
  1660.       UNTIL mouseButtons IN flags;
  1661.    END (* IF pos *);
  1662.  
  1663.    CloseWindow (windowPtr);
  1664.    windowPtr := NIL;
  1665.  
  1666.    (* Ruhmeshalle anzeigen *);
  1667.  
  1668.    Copy (string80, ruhmeshalleFensterName);
  1669.    Concat (string80, string2);
  1670.  
  1671.    innerWidth := 276;
  1672.    innerHeight := 124;
  1673.  
  1674.    windowPtr := OpenWindowTagList (NIL, TAG (tagList,
  1675.       waTitle      , ADR (string80),
  1676.       waInnerWidth , innerWidth,
  1677.       waInnerHeight, innerHeight,
  1678.       waLeft       , (screenPtr^.width - innerWidth) DIV 2,
  1679.       waTop        , (screenPtr^.height - innerHeight) DIV 2,
  1680.       waFlags      , CAST (LONGINT, WindowFlagSet {windowClose,
  1681.                                                    windowDrag,
  1682.                                                    activate,
  1683.                                                    windowDepth,
  1684.                                                    gimmeZeroZero}),
  1685.       waIDCMP      , CAST (LONGINT, IDCMPFlagSet {closeWindow, refreshWindow,
  1686.                                                   mouseButtons}),
  1687.       tagEnd       , 0));
  1688.  
  1689.    Assert (windowPtr # NIL, ADR (openWindowError));
  1690.    Assert (windowPtr^.userPort # NIL, ADR (userPortError));
  1691.  
  1692.    IF visualInfo = NIL THEN
  1693.       visualInfo := GetVisualInfoA (windowPtr^.wScreen, NIL);
  1694.    END (* IF visualInfo *);
  1695.  
  1696.    DrawBevelBoxA (windowPtr^.rPort, 20, 7, 234, 108, TAG (tagList,
  1697.       gtbbRecessed, 0,
  1698.       gtVisualInfo, visualInfo,
  1699.       tagEnd      , 0));
  1700.  
  1701.    FreeVisualInfo (visualInfo);
  1702.    visualInfo := NIL;
  1703.  
  1704.    WITH intuiText DO
  1705.       leftEdge := 0;
  1706.       topEdge := 12;
  1707.    END (* WITH intuiText *);
  1708.  
  1709.    FOR i := 1 TO 10 DO
  1710.       intuiText.iText := ADR (ruhmeshalle [i].name);
  1711.  
  1712.       IF ruhmeshalle [i].anzM = AnzMinen (spielfeldMax) THEN
  1713.          intuiText.frontPen := blau;
  1714.       END (* IF ruhmeshalle *);
  1715.  
  1716.       IF (i = pos) AND (j = noError) THEN
  1717.          intuiText.frontPen := weiss;
  1718.       END (* IF i *);
  1719.  
  1720.       PrintIText (windowPtr^.rPort, ADR (intuiText), 34, 10 * (i - 1));
  1721.  
  1722.       intuiText.frontPen := schwarz;
  1723.    END (* FOR i *);
  1724.  
  1725.    flags := IDCMPFlagSet {};
  1726.  
  1727.    REPEAT
  1728.       nachricht := GetMsg (windowPtr^.userPort);
  1729.  
  1730.       IF nachricht = NIL THEN
  1731.          WaitPort (windowPtr^.userPort);
  1732.          nachricht := GetMsg (windowPtr^.userPort);
  1733.       END (* IF nachricht *);
  1734.  
  1735.       IF nachricht # NIL THEN
  1736.          flags := nachricht^.class;
  1737.          ReplyMsg (nachricht);
  1738.       END (* IF nachricht *);
  1739.                      
  1740.       IF refreshWindow IN flags THEN
  1741.          BeginRefresh (windowPtr);
  1742.          EndRefresh (windowPtr, TRUE);
  1743.       END (* IF refreshWindow *);
  1744.  
  1745.       IF closeWindow IN flags THEN
  1746.          EXIT (* LOOP *);
  1747.       END (* IF closeWindow *);
  1748.    UNTIL mouseButtons IN flags;
  1749.  
  1750.    CloseWindow (windowPtr);
  1751.    windowPtr := NIL;
  1752. END (* LOOP *);
  1753.  
  1754. (* ------------------------------------------------------------------------------- *)
  1755.  
  1756. CLOSE;
  1757.  
  1758. IF screenPtr # NIL THEN
  1759.    UnlockPubScreen (NIL, screenPtr);
  1760.    screenPtr := NIL;
  1761. END (* IF screenPtr *);
  1762.  
  1763. IF visualInfo # NIL THEN
  1764.    FreeVisualInfo (visualInfo);
  1765.    visualInfo := NIL;
  1766. END (* IF visualInfo *);
  1767.  
  1768. IF windowPtr # NIL THEN
  1769.    IF gList # NIL THEN
  1770.       i := RemoveGList (windowPtr, gList, 5);
  1771.       FreeGadgets (gList);
  1772.       gList := NIL;
  1773.    END (* IF gList *);
  1774.  
  1775.    CloseWindow (windowPtr);
  1776.    windowPtr := NIL;
  1777. END (* IF windowPtr *);
  1778.  
  1779. IF windowPtr2 # NIL THEN
  1780.    CloseWindow (windowPtr2);
  1781.    windowPtr2 := NIL;
  1782. END (* IF windowPtr2 *);
  1783.  
  1784. IF fontPtr # NIL THEN
  1785.    CloseFont (fontPtr);
  1786.    fontPtr := NIL;
  1787. END (* IF fontPtr *);
  1788.  
  1789. END Mine (* MODUL *).